package com.inspur.edp.cef.designtime.api.entity;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.inspur.edp.caf.cef.schema.base.element.impl.DefaultProperty;
import com.inspur.edp.caf.cef.schema.datatype.DataType;
import com.inspur.edp.caf.cef.schema.element.Constraint;
import com.inspur.edp.caf.cef.schema.element.Property;
import com.inspur.edp.cef.designtime.api.IGspCommonDataType;
import com.inspur.edp.cef.designtime.api.IGspCommonField;
import com.inspur.edp.cef.designtime.api.collection.GspAssociationCollection;
import com.inspur.edp.cef.designtime.api.collection.GspEnumValueCollection;
import com.inspur.edp.cef.designtime.api.collection.GspFieldCollection;
import com.inspur.edp.cef.designtime.api.element.ElementDefaultVauleType;
import com.inspur.edp.cef.designtime.api.element.EnumIndexType;
import com.inspur.edp.cef.designtime.api.element.FieldCollectionType;
import com.inspur.edp.cef.designtime.api.element.FieldRepoExtendConfigInfo;
import com.inspur.edp.cef.designtime.api.element.GspAssociation;
import com.inspur.edp.cef.designtime.api.element.GspElementDataType;
import com.inspur.edp.cef.designtime.api.element.GspElementObjectType;
import com.inspur.edp.cef.designtime.api.entity.commonstructure.CefCommonStructureUtil;
import com.inspur.edp.cef.designtime.api.exceptions.CommonEntityErrorCodeEnum;
import com.inspur.edp.cef.designtime.api.exceptions.CommonEntityException;
import com.inspur.edp.cef.designtime.api.json.CefNames;
import com.inspur.edp.cef.designtime.api.util.Guid;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * The Definition Of DimensionInfo
 *
 * @ClassName: DimensionInfo
 * @Author: Benjamin Gong
 * @Date: 2021/1/11 17:13
 * @Version: V1.0
 */
public class GspCommonField implements IGspCommonField, Property {
	// region 私有属性
	@JsonProperty(CefNames.ID)
	private String id = Guid.newGuid().toString();
	@JsonProperty(CefNames.Code)
	private String code = "";
	@JsonProperty(CefNames.Name)
	private String name = "";
	@JsonProperty(CefNames.LabelID)
	private String labelId = "";
	@JsonProperty(CefNames.DataType)
	private GspElementDataType dataType = GspElementDataType.String;
	@JsonProperty(CefNames.DefaultValue)
	private String defaultValue = "";
	@JsonProperty(CefNames.DefaultValueType)
	private ElementDefaultVauleType defaultValueType = ElementDefaultVauleType.Vaule;
	@JsonProperty(CefNames.Length)
	private int length;
	@JsonProperty(CefNames.Precision)
	private int precision;
	@JsonProperty(CefNames.IsVirtual)
	private boolean isVirtual;
	@JsonProperty(CefNames.IsRequire)
	private boolean isRequire;
	@JsonProperty(CefNames.IsMultiLanguage)
	private boolean isMultilLanguage;
	@JsonProperty(CefNames.BelongObject)
	private transient IGspCommonDataType belongObject;
	@JsonProperty(CefNames.ChildElements)
	//todo:j-json
	private transient GspFieldCollection childElements;
	@JsonProperty(CefNames.MappingRelation)
	//todo:j-json
	private transient MappingRelation mappingRelation;
	//todo:j-json
	@JsonIgnore
	private transient GspAssociationCollection childAssociations = new GspAssociationCollection();
	//todo:j-json
	private transient GspEnumValueCollection enumValueCollection;
	@JsonProperty(CefNames.IsRefElement)
	private boolean isRefElement;
	@JsonProperty(CefNames.RefElementID)
	private String refelementId = "";
	private transient GspAssociation parentAssociation;
	@JsonProperty(CefNames.ObjectType)
	private GspElementObjectType objectType = GspElementObjectType.None;
	private CustomizationInfo customizationInfo = new CustomizationInfo();
	@JsonProperty(CefNames.EnumIndexType)
	private EnumIndexType enumIndexType=EnumIndexType.Integer;
	@JsonProperty(CefNames.BeLabel)
	private List<String> beLabel;

	@JsonProperty(CefNames.BizTagIds)
	private List<String> bizTagIds;


	@JsonProperty(CefNames.EnableRtrim)
	private boolean enableRtrim = true;

	@JsonProperty(CefNames.IsBigNumber)
	private boolean bigNumber = false;
	@JsonProperty(CefNames.DefaultValueInfo)
	private DefaultValueInfo defaultValueInfo;
	@JsonProperty(CefNames.DisplayDefaultValue)
	private String  displayDefaultValue;
	@JsonProperty(CefNames.ChangedProperties)
	List<String> changedProperties;
	@JsonProperty(CefNames.ExtendInfo)
	Map<String, String> extendInfo;
	@JsonProperty(CefNames.SelectFieldRepoExtend)
	FieldRepoExtendConfigInfo selectFieldRepoConfig;

	// endregion
	public GspCommonField() {
		setIsRef(false);
		setCollectionType(FieldCollectionType.None);
	}

	// region 公共属性

	public String getID() {
		return id;
	}

	public void setID(String value) {
		id = value;
	}

	public String getCode() {
		return code;
	}

	public void setCode(String value) {
		code = value;
	}

	public String getName() {
		return name;
	}
	public void setName(String value) {
		name = value;
	}

	public String getLabelID() {
		return labelId;
	}

	public void setLabelID(String value) {
		labelId = value;
	}

	public List<String> getBeLabel(){
		if(beLabel==null){
			beLabel=new ArrayList<String>();
			return beLabel;
		}
		return beLabel;
	}
	public void setBeLabel(List<String> value){
		beLabel=value;
	}

	public List<String> getBizTagIds(){
		if(this.bizTagIds==null){
			bizTagIds =new ArrayList<String>();
			return bizTagIds;
		}
		return bizTagIds;
	}
	public void setBizTagIds(List<String> value){
		bizTagIds=value;
	}

	public GspElementDataType getMDataType() {
		return dataType;
	}

	public void setMDataType(GspElementDataType value) {
		dataType = value;
	}

	@Override
	public DefaultValueInfo getDefaultValueInfo() {
		return defaultValueInfo;
	}

	@Override
	public void setDefaultValueInfo(DefaultValueInfo value) {
		this.defaultValueInfo=value;
	}

	public String getDefaultValue() {
		return defaultValue;
	}

	public void setDefaultValue(String value) {
		defaultValue = value;
	}

	@Override
	public String getDisplayDefaultValue() {
		return displayDefaultValue;
	}

	@Override
	public void setDisplayDefaultValue(String value) {
		displayDefaultValue=value;
	}

	@Override
	public final ElementDefaultVauleType getDefaultValueType() {
		return defaultValueType;
	}

	@Override
	public final void setDefaultValueType(ElementDefaultVauleType value) {
		defaultValueType = value;
	}

	@Override
	public GspElementObjectType getObjectType() {
		return objectType;
	}

	public int getLength() {
		return length;
	}

	public void setLength(int value) {
		length = value;
	}

	public int getPrecision() {
		return precision;
	}

	public void setPrecision(int value) {
		precision = value;
	}

	public boolean getIsVirtual() {
		return isVirtual;
	}

	public void setIsVirtual(boolean value) {
		isVirtual = value;
	}

	public boolean getIsRequire() {
		return isRequire;
	}

	public void setIsRequire(boolean value) {
		isRequire = value;
	}

	public boolean getIsMultiLanguage() {
		return isMultilLanguage;
	}

	public void setIsMultiLanguage(boolean value) {
		isMultilLanguage = value;
	}

	public Map<String, String> getExtendInfo() {
		if (extendInfo == null) {
			extendInfo = new HashMap<>();
		}
		return extendInfo;
	}

	public void setExtendInfo(Map<String, String> extendInfo) {
		this.extendInfo = extendInfo;
	}

	public FieldRepoExtendConfigInfo getSelectFieldRepoConfig() {
		return selectFieldRepoConfig;
	}

	public void setSelectFieldRepoConfig(FieldRepoExtendConfigInfo selectFieldRepoConfig) {
		this.selectFieldRepoConfig = selectFieldRepoConfig;
	}
	/**
	 * 是否从其他业务实体引用字段
	 */
	private boolean privateIsRef;

	/**
	 * 获取是否从其他业务实体引用字段
	 *
	 * @return 是否从其他业务实体引用字段
	 */
	public boolean getIsRef() {
		return privateIsRef;
	}

	public void setIsRef(boolean value) {
		privateIsRef = value;
	}
	/**
	 *  bigNumber
	 */
	public boolean isBigNumber(){
		return this.bigNumber;
	}
	public void  setIsBigNumber(boolean value){
		this.bigNumber = value;
	}

	public IGspCommonDataType getBelongObject() {
		if (this.getIsRefElement() && belongObject == null) {
			return this.getParentAssociation().getBelongElement().getBelongObject();
		}
		return belongObject;
	}

	public void setBelongObject(IGspCommonDataType value) {
		belongObject = value;
	}

	public GspFieldCollection getChildElements() {
		if (childElements == null) {
			childElements = new GspFieldCollection();
		}
		return childElements;
	}

	public void setChildElements(GspFieldCollection value) {
		childElements = value;
	}

	public MappingRelation getMappingRelation() {
		if (mappingRelation == null) {
			mappingRelation = new MappingRelation();
		}
		return mappingRelation;
	}

	public void setMappingRelation(MappingRelation mappingInfos) {
		mappingRelation = mappingInfos;
	}

	/**
	 * /////关联引用
	 */
	public GspAssociationCollection getChildAssociations() {
		return childAssociations;
	}

	public void setChildAssociations(GspAssociationCollection value) {
		childAssociations = value;
	}

	public final boolean getHasAssociation() {
		if (getChildAssociations() == null || getChildAssociations().size() == 0) {
			return false;
		}
		return true;
	}

	public GspEnumValueCollection getContainEnumValues() {
		if(enumValueCollection==null)
			enumValueCollection=new GspEnumValueCollection();
		return enumValueCollection;
	}

	public void setContainEnumValues(GspEnumValueCollection value) {
		enumValueCollection = value;
	}

	public boolean getIsRefElement() {
		return isRefElement;
	}

	public void setIsRefElement(boolean value) {
		isRefElement = value;
	}

	public String getRefElementId() {
		return refelementId;
	}

	public void setRefElementId(String value) {
		refelementId = value;
	}

	public GspAssociation getParentAssociation() {
		return parentAssociation;
	}

	public void setParentAssociation(GspAssociation value) {
		parentAssociation = value;
	}

	public void setObjectType(GspElementObjectType value) {
		objectType = value;
	}

	/**
	 * 是否启用业务字段
	 */
	private boolean privateIsUdt;

	public boolean getIsUdt() {
		return privateIsUdt;
	}

	public void setIsUdt(boolean value) {
		privateIsUdt = value;
	}

	/**
	 * 业务字段包名
	 */
	private String privateUdtPkgName;

	public String getUdtPkgName() {
		return privateUdtPkgName;
	}

	public void setUdtPkgName(String value) {
		privateUdtPkgName = value;
	}

	/**
	 * 业务字段ID
	 */
	private String privateUdtID;

	public String getUdtID() {
		return privateUdtID;
	}

	public void setUdtID(String value) {
		privateUdtID = value;
	}

	public String getRefBusinessFieldId() {
		return refBusinessFieldId;
	}

	public void setRefBusinessFieldId(String refBusinessFieldId) {
		this.refBusinessFieldId = refBusinessFieldId;
	}

	/**
	 * 引用的业务字段ID
	 */
	private String refBusinessFieldId;

	public String getRefBusinessFieldName() {
		return refBusinessFieldName;
	}

	public void setRefBusinessFieldName(String refBusinessFieldName) {
		this.refBusinessFieldName = refBusinessFieldName;
	}

	private String refBusinessFieldName;

	/**
	 * 业务字段ID
	 */
	private String privateUdtName;

	public final String getUdtName() {
		return privateUdtName;
	}

	public final void setUdtName(String value) {
		privateUdtName = value;
	}

	private FieldCollectionType privateCollectionType = FieldCollectionType.forValue(0);

	public FieldCollectionType getCollectionType() {
		return privateCollectionType;
	}

	public final void setCollectionType(FieldCollectionType value) {
		privateCollectionType = value;
	}

	/**
	 * 是否udt关联带出字段
	 */
	private boolean privateIsFromAssoUdt;

	public final boolean getIsFromAssoUdt() {
		return privateIsFromAssoUdt;
	}

	public final void setIsFromAssoUdt(boolean value) {
		privateIsFromAssoUdt = value;
	}

	/**
	 * 国际化项前缀
	 */
	private String privateI18nResourceInfoPrefix;

	public final String getI18nResourceInfoPrefix() {
		return privateI18nResourceInfoPrefix;
	}

	public final void setI18nResourceInfoPrefix(String value) {
		privateI18nResourceInfoPrefix = value;
	}

	/**
	 * 动态属性设置
	 */
	private DynamicPropSetInfo privateDynamicPropSetInfo = new DynamicPropSetInfo();

	public final DynamicPropSetInfo getDynamicPropSetInfo() {
		return privateDynamicPropSetInfo;
	}

	public final void setDynamicPropSetInfo(DynamicPropSetInfo value) {
		privateDynamicPropSetInfo = value;
	}


	public CustomizationInfo getCustomizationInfo() {
		return customizationInfo;
	}

	public void setCustomizationInfo(CustomizationInfo customizationInfo) {
		this.customizationInfo = customizationInfo;
	}

	/**
	 * 索引类型
	 */
	public  EnumIndexType getEnumIndexType(){
		return enumIndexType;
	}

	public  void setEnumIndexType(EnumIndexType value){
		enumIndexType=value;
	}
	// endregion

	// region 方法
	public final boolean hasNoneRefElementInAssociation() {
		if (getHasAssociation() == false) {
			return false;
		}

		return false;
	}

	/**
	 * 若当前字段引用联动关联udt,返回是否包含非udt带出字段
	 *
	 * @return
	 */
	public final boolean containRefElementNotFromAssoUdt() {
		if (!getIsUdt() || getObjectType() != GspElementObjectType.Association) {
			throw CommonEntityException.createException(CommonEntityErrorCodeEnum.GSP_BEMODEL_COMMON_ENTITY_0002, getCode(), "ContainRefElementNotFromAssoUdt");
		}
		if (getChildAssociations() == null || getChildAssociations().size() == 0) {
			throw CommonEntityException.createException(CommonEntityErrorCodeEnum.GSP_BEMODEL_COMMON_ENTITY_0003, getCode());
		}
		for (GspAssociation asso : getChildAssociations()) {
			if (asso.getRefElementCollection() == null || asso.getRefElementCollection().size() == 0) {
				throw CommonEntityException.createException(CommonEntityErrorCodeEnum.GSP_BEMODEL_COMMON_ENTITY_0004, getCode());
			}
			for (IGspCommonField field : asso.getRefElementCollection()) {
				if (!field.getIsFromAssoUdt()) {
					return true;
				}
			}
		}
		return false;
	}

	@Override
	public IGspCommonField clone(IGspCommonDataType absObj, GspAssociation association) {
		GspCommonField newObj = null;
		try {
			newObj = (GspCommonField) super.clone();
		} catch (CloneNotSupportedException e) {
			return null;
		}
		if (newObj == null) {
			return null;
		}
		newObj.belongObject = absObj;
		newObj.parentAssociation = association;
		if (childAssociations != null) {
			newObj.childAssociations = new GspAssociationCollection();
			for (GspAssociation item : childAssociations) {
				newObj.childAssociations.add(item.clone(newObj));
			}
		}
		if (enumValueCollection != null) {
			newObj.enumValueCollection = enumValueCollection.clone();
		}
		return newObj;
	}

	@Override
	public List<String> getChangedProperties() {
		if(this.changedProperties==null)
			this.changedProperties=new ArrayList<>();
		return this.changedProperties;
	}

	@Override
	public void setChangedProperties(List<String> value) {
		this.changedProperties=value;
	}

	// endregion

	// region Property
	@Override
	public String getId() {
		return getID();
	}

	@Override
	public String getDescription() {
		return "";
	}

	@Override
	public DataType getPropertyType() {
		return getCefCommonStructureUtil().getCommonFieldDataType(this);
	}

	@Override
	public Boolean isRequired() {
		return getIsRequire();
	}

	@Override
	public Constraint getConstraint() {
		return null;
	}

	@Override
	public String getKind() {
		return new DefaultProperty().getKind();
	}

	protected CefCommonStructureUtil getCefCommonStructureUtil()
	{
		return null;
	}

	@Override
	public List<String> getExtensionKeys() {
	  ArrayList<String> list=new ArrayList<>();
    list.add("UseLabelId");
    list.add("LabelId");
    return list;
	}

	@Override
	public String getExtensionValue(String s) {
	  switch (s){
      case "UseLabelId":
        return "true";
      case "LabelId":
        return this.getLabelID();
        default:
          return null;
    }
	}

	public boolean isEnableRtrim() {
		return enableRtrim;
	}

	public void setEnableRtrim(boolean value) {
		this.enableRtrim = value;
	}
	// endregion
}
